package org.cosmact.designer.vxml.gefeditor.i118n;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Help class to generate messages files. Just use for development.
 * 
 *@author YeXiaowei 234aini@gmail.com
 * 
 */
public class MessageHelper {
	private static final String LINE_CONN = "=";
	File file;
	IMessageSource messageSource;

	static interface IMessageSource {
		public List<String> getMessageKeys();
	}

	public MessageHelper(File file, IMessageSource source) {
		this.file = file;
		this.messageSource = source;
	}

	/**
	 * Read message keys form Enum class and write new lines to message files
	 * 
	 * @param args
	 */
	public static void main(String[] args) {

		IMessageSource source = new IMessageSource() {
			@Override
			public List<String> getMessageKeys() {
				List<String> lines = new ArrayList<String>();
				for (Field message : VxmlEditorMessages.class.getDeclaredFields()) {
					if (Modifier.isPublic(message.getModifiers()))
						// filter BUNDLE_NAME field
						lines.add(message.getName());
				}
				return lines;
			}
		};

		File file = new File("src");
		File[] listFiles = file.listFiles();
		for (File mfile : listFiles) {
			if (mfile.isDirectory()) {
				break;
			}
			if (mfile.isFile() && mfile.getName().endsWith(".properties")) {
				MessageHelper messageHelper = new MessageHelper(mfile, source);
				messageHelper.writeMessages();
			}
		}

	}

	public void writeMessages() {
		List<String> existLines = readExistLines();
		List<String> enumLines = getNewLinesKeys();
		Map<String, String> finalLines = new HashMap<String, String>();
		for (String line : existLines) {
			String[] split = line.split("=");
			if (split.length == 1) {
				finalLines.put(split[0], "");
			} else if (split.length == 2) {
				finalLines.put(split[0], split[1]);
			}
		}

		for (String newKey : enumLines) {
			if (!finalLines.containsKey(newKey)) {
				finalLines.put(newKey, "");
			}
		}
		sort(finalLines);
		writeResult(finalLines);
	}

	private List<String> readExistLines() {
		List<String> lines = new ArrayList<String>();
		try {
			FileReader reader = new FileReader(file);
			BufferedReader br = new BufferedReader(reader);
			String line = br.readLine();
			while (line != null) {
				lines.add(line);
				line = br.readLine();
			}
			br.close();
			reader.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return lines;
	}

	private List<String> getNewLinesKeys() {
		if (messageSource == null) {
			throw new IllegalArgumentException();
		}
		return messageSource.getMessageKeys();
	}

	@SuppressWarnings("unchecked")
	private void sort(Map<String, String> linesMap) {
		Collections.sort(new ArrayList(linesMap.entrySet()), new Comparator() {
			@Override
			public int compare(Object o1, Object o2) {
				Map.Entry obj1 = (Map.Entry) o1;
				Map.Entry obj2 = (Map.Entry) o2;
				return ((String) obj1.getKey()).compareTo((String) obj2
						.getKey());
			}
		});
	}

	private void writeResult(Map<String, String> finalLines) {
		String lineSeparator = System.getProperty("line.separator");
		FileWriter fw = null;
		BufferedWriter writer = null;
		try {
			fw = new FileWriter(file);
			writer = new BufferedWriter(fw);
			for (String key : finalLines.keySet()) {
				StringBuilder stringBuilder = new StringBuilder();
				stringBuilder.append(key);
				stringBuilder.append(LINE_CONN);
				stringBuilder.append(finalLines.get(key));
				writer.write(stringBuilder.toString());
				writer.write(lineSeparator);
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				writer.close();
				fw.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

	}
}
